// Copyright (c) 2021 Presto Labs Pte. Ltd.
// Author: xguo

#include "coin2/strategy/umm/fill_stats.h"

const double eps = 1e-10;

int main() {
  xguo::FillStatsConfig config;
  xguo::FillStats fill_stats(config);

  xguo::Fill fill;
  const xguo::Fill* bfill = nullptr;
  const xguo::Fill* sfill = nullptr;

  // buy fill
  fill.fill_price = 100;
  fill.fill_qty = 1;
  fill_stats.UpdateByFill(fill);

  bfill = fill_stats.lowest_fill_buy();
  sfill = fill_stats.highest_fill_sell();

  CHECK_EQ(sfill, nullptr);
  CHECK_NEAR(bfill->fill_price, 100, eps);
  CHECK_NEAR(bfill->fill_qty, 1, eps);

  // sell fill
  fill.fill_price = 101;
  fill.fill_qty = -1;
  fill_stats.UpdateByFill(fill);

  bfill = fill_stats.lowest_fill_buy();
  sfill = fill_stats.highest_fill_sell();

  CHECK_EQ(bfill, nullptr);
  CHECK_EQ(sfill, nullptr);

  // sell fill
  fill_stats.UpdateByFill(fill);

  fill.fill_price = 100;
  fill.fill_qty = 3;
  fill_stats.UpdateByFill(fill);

  bfill = fill_stats.lowest_fill_buy();
  sfill = fill_stats.highest_fill_sell();
  CHECK_EQ(sfill, nullptr);
  LOG(INFO) << bfill->fill_price << ", " << bfill->fill_qty;

  const int64_t T = 20'000'000'000LL;
  xguo::OhlcCalculator ohlc(T);
  xguo::Bbo bbo;

  const int64_t start_ts = xguo::GetCurrentTimestamp();
  const int64_t delta = T/5;

  bbo.timestamp = start_ts;
  bbo.midp = 100;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 101;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 99;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 105;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 115;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 102;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << "ohlc: " << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 90;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << "ohlc: " << ohlc.size();

  bbo.timestamp += delta;
  bbo.midp = 95;
  ohlc.UpdateByBbo(bbo);
  LOG(INFO) << "ohlc: " << ohlc.size();

  for (const auto& each : ohlc.IterOhlc()) {
    LOG(INFO) << "+++++++++++++++++++";
    LOG(INFO) << "open: " << each.open << "\n";
    LOG(INFO) << "high: " << each.high << "\n";
    LOG(INFO) << "low: " << each.low << "\n";
    LOG(INFO) << "close: " << each.close << "\n";
    LOG(INFO) << "rtn: " << each.rtn << "\n";
  }

  return 0;
}
